//===============================================
// Pos Norm Tex Shader
// Reverse tri
//===============================================

#include "ShaderHelp.fxh"

static const float SHADOW_EPSILON = 0.001f;
static const float SMAP_SIZE = 1024.0f;
static const float SMAP_DX = 1.0f / SMAP_SIZE;

cbuffer cbPerFrame
{
	Light gLight;
	int gLightType;
	float3 gEyePosW;
};

cbuffer cbPerObject
{
	matrix g_World : World;
	matrix g_WorldInv : WorldInverseTranspose;
	matrix g_WVP : WorldViewProjection;
	matrix g_ViewInv : ViewInverse;
	matrix g_LightWVP : LightWorldViewProj;
};

Texture2D diffuseTexture : Diffuse;
Texture2D ShadowMap : Shadow;

float3 gPosLight : LIGHTPOS = {-70, 800, 200};
float4 gLightColor : LIGHTCOL = {0.9f, 0.9f, 0.9f, 1.0f};
float4 gLightSpec : LIGHTSPEC = {1.0f, 1.0f, 1.0f, 1.0f};
float4 gLightAmbient : LIGHTAMBIENT = {0.3f, 0.3f, 0.3f, 1.0f};

SamplerState diffuseSampler
{
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

SamplerState ShadowSampler
{
	Filter = MIN_MAG_MIP_POINT;
	AddressU = Clamp;
	AddressV = Clamp;
};

struct VS_INPUT
{
    float3 Pos          : POSITION;         //position
    float3 Norm		: NORMAL;
    float2 Tex          : TEXCOORD0;        //texture coordinate
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float4 WorldPos : TEXCOORD1;
    float2 Tex : TEXCOORD2;
    float4 projTex : TEXCOORD3;
};


//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    
    float4 hPos = float4(input.Pos, 1);
    output.Pos = mul(hPos, g_WVP);
    output.WorldPos = mul(hPos, g_World);
    output.Norm = mul(input.Norm, (float3x3)g_World);
    output.Norm = -normalize(output.Norm);
    output.Tex = input.Tex;
    
    output.projTex = mul(float4(input.Pos, 1.0f), g_LightWVP);
    
    output.projTex.xyz /= output.projTex.w;
    output.projTex.x = +0.5f * output.projTex.x + 0.5f;
	output.projTex.y = -0.5f * output.projTex.y + 0.5f;
    
    return output;
}
	
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------

float4 PS( PS_INPUT input) : SV_Target
{
	float r = ShadowMap.Sample(ShadowSampler, input.projTex).r;
	
	return float4(r,r,r, 1.0f);
}


//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------

RasterizerState DisableCulling
{
    CullMode = NONE;
};

RasterizerState EnableCulling
{
    CullMode = Back;
    //FillMode = Wireframe;
    FrontCounterClockwise = false;
};

DepthStencilState DepthEnabling
{
	DepthEnable = TRUE;
};

BlendState DisableBlend
{
	BlendEnable[0] = FALSE;
};


technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
        
        SetRasterizerState(EnableCulling);       
		//SetDepthStencilState(DepthEnabling, 0);
		SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

